/*
 *接口编写处...
*如果接口需要做Action的权限验证，请在Action上使用属性
*如: [ApiActionPermission("StorageChannel",Enums.ActionPermissionOptions.Search)]
 */
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using Mercury.Entity.DomainModels;
using Mercury.Business.IServices;
using Mercury.Core.Utilities;
using Mercury.Business.IRepositories;
using Mercury.Core.BaseProvider;
using System.Linq;

namespace Mercury.Business.Controllers
{
    public partial class StorageChannelController
    {
        private readonly IStorageChannelService _service;//访问业务代码
        private readonly IStorageChannelRepository _repository;
        private readonly IHttpContextAccessor _httpContextAccessor;

        [ActivatorUtilitiesConstructor]
        public StorageChannelController(
            IStorageChannelService service, IStorageChannelRepository repository,
            IHttpContextAccessor httpContextAccessor
        )
        : base(service)
        {
            _service = service;
            _repository = repository;
            _httpContextAccessor = httpContextAccessor;
        }

        [Route("GetStorageChannel"), HttpGet]
        public async Task<WebResponseContent> GetStagingAreas()
        {
            var areas = await _repository.FindAsync(c => c.Enable == 1);
            var data = areas.Select(c => new { c.Id, c.StorageChannelNo, c.StorageChannelName, ParentId = "-" }).OrderBy(c => c.StorageChannelName);
            return new WebResponseContent() { Status = true, Data = data };
        }
        [Route("GetStock/{id}"), HttpGet]
        public async Task<WebResponseContent> GetStock(string id)
        {
            var joinQueryable = from p in _repository.DbContext.Set<WarehouseLocation>().Where(c => c.StorageChannelId == id && c.DeletionFlag != 1)
                                join d in _repository.DbContext.Set<MaterialBox>()
                                on p.CurrentMaterialBox equals d.BoxNo into DD
                                from dc in DD.DefaultIfEmpty()
                                select new
                                {
                                    p.Enable,
                                    p.WarehouseLocationNo,
                                    p.TheColumn,
                                    p.TheRow,
                                    p.CurrentMaterialBox,
                                    dc.MaterialName,
                                    dc.MaterialId,
                                    dc.BatchNumber,
                                    dc.OrderNumber,
                                    p.TheLevel,
                                    dc.MaterialWeight   ,
                                    p.IsOccupy
                                };

            var data = joinQueryable.ToList();
            //_repository.DbContext.Set<StagingLocation>().Where(c => c.StagingAreaId == id && c.DeletionFlag != 1).ToList();

            var rows = data.OrderByDescending(c => c.TheLevel).GroupBy(c => c.TheLevel).Select(c => new
            {
                c.Key,
                Sort = c.Min(x => x.TheLevel),
                Data = c.ToList()
            });

            var result = new List<Dictionary<string, object>>();
            var rowsList = rows.OrderByDescending(c => c.Sort).ToList();
            for (int i = 0; i < rowsList.Count(); i++)
            {
                var dic = new Dictionary<string, object>();
                dic.Add("Key", rowsList[i].Key);

                WarehouseLocation last = null;
                var tempList = rowsList[i].Data.OrderBy(c => c.TheRow).ToList();
                var tmpCol = tempList.Select(c =>
                {
                    var tempLocation = new WarehouseLocation()
                    {
                        TheLevel = c.TheLevel,
                        TheRow = c.TheRow
                    };
                    var offset = 0;
                    if (last == null)
                    {
                        if (tempLocation.TheRow > 1)
                        {
                            offset = tempLocation.TheRow - 1;
                        }
                    }
                    else if (last.TheRow == tempLocation.TheRow)
                    {
                        tempLocation.TheRow += 1;
                    }
                    else if (last.TheRow + 1 != tempLocation.TheRow )
                    {
                        offset = tempLocation.TheRow - last.TheRow - 1;
                    }
                    last = tempLocation;
                    return new
                    {
                        c.Enable,
                        c.WarehouseLocationNo,
                        c.TheColumn,
                        c.TheRow,
                        Offset = offset,
                        c.CurrentMaterialBox,
                        c.MaterialId,
                        c.MaterialName,
                        c.OrderNumber,
                        c.BatchNumber,
                        c.MaterialWeight   ,
                        c.IsOccupy
                    };
                });
                dic.Add("Cols", tmpCol);
                result.Add(dic);
            }
            var maxCol = rows.Max(c => c.Data.Max(c => c.TheRow));
            return new WebResponseContent() { Status = true, Data = new { Span = 24 / maxCol, Result = result } };
        }
    }
}
